package com.hoyin.javaproj;

import java.util.Iterator;

public class Conditions<Boolean> implements Iterable<java.lang.Boolean> {
	private GenericsArray<java.lang.Boolean> conditions = new GenericsArray<>();
	private GenericsArray<String> conditionTags = new GenericsArray<>();

	public Conditions() {}

	public void addCondition(java.lang.Boolean condition) {
		conditions.append(condition);
	}

	public void addCondition(String tag, java.lang.Boolean condition) {
		if (isAlreadyHave(tag)) {
			conditions.update(this.getIndex(tag), condition);
		} else {
			conditions.append(condition);
			conditionTags.append(tag);
		}
	}

	public void removeCondition(int index) {
		conditions.remove(index);
		conditionTags.remove(index);
	}

	public void removeCondition(String tag) {
		int targetIndex = -1;
		for (int currentIndex = 0; currentIndex < conditionTags.getSize(); currentIndex++) {
			if (conditionTags.getItem(currentIndex).equals(tag)) {
				targetIndex	= currentIndex;
			}
		}
		if (targetIndex != -1) {
			conditions.remove(targetIndex);
			conditionTags.remove(targetIndex);
		}
	}

	public boolean isAlreadyHave(String tag) {
		return getIndex(tag) != -1;
	}

	private int getIndex(String tag) {
		for (int i = 0; i < conditionTags.getSize(); i++) {
			if (conditionTags.getItem(i).equals(tag)) return i;
		}
		return -1;
	}

	public boolean isAllTrue() {
		for (int i = 0; i < conditions.getSize(); i++) {
			if (!this.isTrue(i)) return false;
		}
		return true;
	}

	public boolean isAllFalse() {
		for (int i = 0; i < conditions.getSize(); i++) {
			if (this.isTrue(i)) return false;
		}
		return true;
	}

	public boolean haveTrue(int[] conditionIndexes) {
		for (int i : conditionIndexes) {
			if (conditions.getItem(i)) return true;
		}
		return false;
	}

	public boolean areTrue(int[] conditionIndexes) {
		for (int conditionIndex : conditionIndexes) {
			if (!this.isTrue(conditionIndex)) return false;
		}
		return true;
	}

	public boolean isTrue(int conditionIndex) {
		return conditions.getItem(conditionIndex);
	}

	public boolean isTrue(String tag) {
		return conditions.getItem(this.getIndex(tag));
	}

	public boolean areTrue(String[] tags) {
		for (String tag : tags) {
			if (!isTrue(tag)) return false;
		}
		return true;
	}

	@Override
	public Iterator<java.lang.Boolean> iterator() {
		return new ConditionsIterator();
	}

	private class ConditionsIterator implements Iterator<java.lang.Boolean> {
		private int n = conditions.getSize();

		@Override
		public boolean hasNext() {
			return n > 0;
		}

		@Override
		public java.lang.Boolean next() {
			return conditions.getItem(--n);
		}
	}

	public static void main() {
		Conditions<java.lang.Boolean> conditions = new Conditions<>();
		conditions.addCondition("c1", true);
		conditions.addCondition("c2", false);
		conditions.addCondition("c3", false);
		conditions.addCondition("c4", true);
		System.out.println(conditions.isTrue("c1"));//true
		System.out.println(conditions.isTrue("c4"));//true
		System.out.println(conditions.isTrue("c2"));//false
		System.out.println(conditions.areTrue(new String[] {"c1", "c2"}));//false
		System.out.println(conditions.areTrue(new String[] {"c1", "c4"}));//true
		System.out.println(conditions.areTrue(new String[] {"c2", "c3"}));//false
		conditions.addCondition("c4", false);
		System.out.println(conditions.isTrue("c4"));//false
		System.out.println(conditions.areTrue(new String[] {"c1", "c2", "c4"}));//false
	}
}

